package actor.route.consistenthashing

import actor.route.consistenthashing.MoneyCounter3.{OneHand, ReportTotal}
import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
import akka.routing.ConsistentHashingPool
import akka.routing.ConsistentHashingRouter.ConsistentHashableEnvelope

/**
 * @Description: The messages can be be wrapped in a [[akka.routing.ConsistentHashingRouter.ConsistentHashableEnvelope]]
 * @Author: DJJ
 * @Date: 2019/12/19 20:04
 */
object MoneyCounter3 {

  sealed trait Counting

  case class OneHand(cur: String, amt: Double) extends Counting

  case class ReportTotal(cur: String) extends Counting

}
class MoneyCounter3 extends Actor with ActorLogging {
  var currency: String = null
  var amount: Double = 0
  override def receive: Receive = {
    case OneHand(cur,amt) =>
      currency = cur
      amount += amt
      log.info(s"${self.path.name} received one hand of $amt$cur")
    case ReportTotal(_) =>
      log.info(s"${self.path.name} has a total of $amount$currency")
  }
}
object HashingRouter3 extends App {
  import MoneyCounter3._

  val currencies = List("RMB","USD","EUR","JPY","GBP","DEM","HKD","FRF","CHF")

  val routerSystem = ActorSystem("routerSystem")


  /**
   * 特别要注意nrOfInstances，这个参数必须比消息类型的数量大才行，否则Router会错误引导消息
   */
  val router = routerSystem.actorOf(ConsistentHashingPool(
    //mcHashMapping 定义消息的类型
    nrOfInstances = 5 ,virtualNodesFactor = 2)
    .props(Props[MoneyCounter3]),name = "moneyCounter" )

  /**
   *  得指定
   */
  router ! ConsistentHashableEnvelope(OneHand("RMB",10.00),"RMB")
  router ! ConsistentHashableEnvelope(OneHand("USD",10.00),"USD")
  router ! ConsistentHashableEnvelope(OneHand("HKD",10.00),"HKD")
  router ! ConsistentHashableEnvelope(OneHand("RMB",10.00),"RMB")
  router ! ConsistentHashableEnvelope(OneHand("CHF",10.00),"CHF")


  router ! ConsistentHashableEnvelope(ReportTotal("RMB"),"RMB")
  router ! ConsistentHashableEnvelope(ReportTotal("USD"),"USD")

  scala.io.StdIn.readLine()

  routerSystem.terminate()
  /**
   *  效果是一样的,效果和松耦合最好的是 MoneyCounter2
   */
}